package parsers;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.Iterator;

import main.WoTCWBot;

import org.json.JSONArray;
import org.json.JSONObject;

import utils.Utils;

import config.Constants;
import data.bot.CombatContainer;
import data.wg.WGCombatant;
import data.wg.MapInfo;
import data.wg.WGScheduledBattle;
import data.wg.WGCombat;
import data.wg.WGProvince;

public class JSONParser 
{
	public WoTCWBot m;
	public JSONParser(WoTCWBot m)
	{
		this.m=m;
	}
	
	public boolean init()
	{
		return initRegionURLS() && initClanName();
	}
	
	private boolean initRegionURLS()
	{
		WoTCWBot.LOGGER.debug("setting RegionURLS");
		try
		{
			for(int i=3;i<6;i++)
			{
				Constants.URLS_REGIONS.add(new URL("http://cw.worldoftanks.eu/clanwars/maps/provinces/regions/"+i+"/?ct=json"));
			}
			WoTCWBot.LOGGER.debug("RegionURLS set successfully");
			return true;
		}
		catch(Exception e)
		{
			WoTCWBot.LOGGER.fatal("can not add RegionURLS!"+e);
			e.printStackTrace();
		}
		return false;
		
	}
	
	public void parseRegions() 
	{
		WoTCWBot.LOGGER.trace("parsing regions");
		try
		{
			for(URL url: Constants.URLS_REGIONS)
			{
				WoTCWBot.LOGGER.trace("requesting "+url);
				HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
				httpConn.setDoOutput(true);
				String response = Utils.convertStreamToString(httpConn.getInputStream());
				parseRegion(response);
			}
			WoTCWBot.LOGGER.trace("regions parsed successfully");
		}
		catch(Exception e)
		{
			WoTCWBot.LOGGER.fatal("parsing regions failed: "+e);
		}
	}
	
	public void parseRegion(String response) throws Exception
	{
		JSONObject jsonRegion = new JSONObject(response);
		JSONObject jsonProvinces = jsonRegion.getJSONObject("provinces");
		Iterator<String> provincesIterator = jsonProvinces.keys();
		
		while(provincesIterator.hasNext())
		{
			String provinceID = provincesIterator.next();					
			if(provinceID.equals("null"))
			{
				continue;
			}
			JSONObject jsonProvince = jsonProvinces.getJSONObject(provinceID);
			
			WGProvince tempProvince = new WGProvince();
			tempProvince.clan = jsonProvince.getString("clan");
//			tempProvince.status = province.getString("status");
//			tempProvince.primetimeturn = province.getInt("prime_time_turn");
			tempProvince.name = jsonProvince.getString("name");
//			tempProvince.revenue = province.getInt("revenue");
//			tempProvince.url = province.getString("url");
			tempProvince.primetime = jsonProvince.getLong("prime_time");
			Calendar now = Calendar.getInstance();
			Calendar prime = Calendar.getInstance();
			prime.setTimeInMillis(tempProvince.primetime*1000);
			prime.set(Calendar.DAY_OF_MONTH, now.get(Calendar.DAY_OF_MONTH));
			tempProvince.primetime = prime.getTimeInMillis()/1000;
//			tempProvince.mapId = province.getString("mapId");
//			tempProvince.clanId = jsonProvince.getInt("clanId");
//			tempProvince.capuredAt = province.getInt("captured_at");
//			tempProvince.periphery = province.getString("periphery");
			tempProvince.mutiny = jsonProvince.getBoolean("mutiny");
			if(tempProvince.mutiny)
			{
				tempProvince.landingCompetitorsCount = jsonProvince.getInt("landing_competitors_count");
			}
			
			tempProvince.verboseName = jsonProvince.getString("verbose_name");
			tempProvince.landingUrl = jsonProvince.getString("landing_url");
//			tempProvince.combatsCount = province.getInt("combats_count");
//			tempProvince.mapId = province.getString("mapId");
			
			if(!jsonProvince.isNull("landing_final_battle_time"))
			{
				tempProvince.landingFinalBattleTime = jsonProvince.getLong("landing_final_battle_time");
			}
			JSONObject jsonCombats = jsonProvince.getJSONObject("combats");

			Iterator<String> combatiterator = jsonCombats.keys();
			MapInfo mf=null;
			
			while(combatiterator.hasNext())
			{
				//Combat
				String combatIdString = combatiterator.next();
				int combatId = Integer.parseInt(combatIdString);
				
				if(!combatIdString.equals("null"))
				{
					JSONObject jsonCombat = jsonCombats.getJSONObject(combatIdString);
					WGCombat tempWGCombat = new WGCombat(combatId);
					
					
					
					tempWGCombat.at = jsonCombat.getLong("at");
					tempWGCombat.type = jsonCombat.getString("type");
					
					
					//Combatants
					JSONObject jsonCombatants = jsonCombat.getJSONObject("combatants");
					Iterator<String> jsonCombatantsIterator = jsonCombatants.keys();
					
					WGCombatant ownClan=null;
					while(jsonCombatantsIterator.hasNext())
					{
						String tempCombatantName = jsonCombatantsIterator.next();
						JSONObject jsonCombatant = jsonCombatants.getJSONObject(tempCombatantName);
						WGCombatant tempCombatant = new WGCombatant(tempCombatantName);
						
						if(tempCombatantName.equals(Constants.CLAN_NAME))
						{
							ownClan=tempCombatant;
						}
						if(!jsonCombatant.isNull("at"))
						{
							tempCombatant.at = new Long(jsonCombatant.getLong("at"));
						}
						//

						tempWGCombat.combatants.add(tempCombatant);
					}
					if(ownClan!=null)
					{
						mf = HTMLParser.getMapInfo(tempProvince.name);
						tempProvince.FULLNAME=mf.name;
						tempWGCombat.ARENA=mf.mapname;
						tempWGCombat.PROVINCE = mf.name;
						
						m.handleInvolvedWGCombat(tempWGCombat,ownClan,tempProvince);
					}
				}
			}
			if(tempProvince.mutiny&&tempProvince.clan.equals(Constants.CLAN_NAME))
			{
				if(mf==null)
				{
					mf = HTMLParser.getMapInfo(tempProvince.name);
					tempProvince.FULLNAME=mf.name;
				}
				m.handleLanding(tempProvince);
			}
		}
	}
	private boolean initClanName()
	{
		/*
		 * get the clan name via ID
		 */
		WoTCWBot.LOGGER.debug("getting clanname");
		try
		{
			URL ClanURL = new URL("http://worldoftanks.eu/community/clans/"+Constants.CLAN_ID+"/api/1.0/?source_token=WG-WoT_Assistant-1.3.2");
			HttpURLConnection httpConn = (HttpURLConnection) ClanURL.openConnection();
			httpConn.setDoOutput(true);
			String response = Utils.convertStreamToString(httpConn.getInputStream());
			if(response!=null&&!response.equals(""))
			{
				JSONObject json = new JSONObject(response);
				JSONObject data = json.getJSONObject("data");
				Constants.CLAN_NAME = data.getString("name");
			}
			WoTCWBot.LOGGER.debug("clanname set to "+Constants.CLAN_NAME);
			return true;
		}
		catch(Exception e)
		{
			WoTCWBot.LOGGER.debug("could not get clanname! "+e);
			e.printStackTrace();
			Constants.CLAN_NAME= "COULD NOT GET CLANNAME";
		}
		return false;
	
	}
	
	public void parseBattleScheduleOfOwnClan()
	{
		WoTCWBot.LOGGER.trace("parsing battleschedule");
		WoTCWBot.scheduledBattlesOfOwnClanList.clear();
		try
		{
			/*
			 * getting the JSON-Data from WG
			 */
			HttpURLConnection httpConn = (HttpURLConnection) Constants.URL_BATTLE_SCHEDULE.openConnection();
			httpConn.setDoOutput(true);
			httpConn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
			String response = Utils.convertStreamToString(httpConn.getInputStream());
			//System.out.println(response);
			JSONObject json =new JSONObject(response);
			
			
			
			if(json.getString("result").equals("success"))
			{
				JSONObject requestData = json.getJSONObject("request_data");
				JSONArray items = requestData.getJSONArray("items");
				
				
				/*
				 * iterating over the battles
				 */
				for(int i=0;i< items.length();i++)
				{
					/*
					 * processing a single battle
					 */
					
					WGScheduledBattle tempBattle = new WGScheduledBattle();
					JSONObject item = items.getJSONObject(i);
					JSONArray provinces = item.getJSONArray("provinces");
					JSONObject province = provinces.getJSONObject(0);
					
					
					tempBattle.nameOfProvince = province.getString("name");
					tempBattle.idOfProvince = province.getString("id");
					tempBattle.started = item.getBoolean("started");
					
					tempBattle.typeOfBattle = item.getString("type");
					JSONArray arenas = item.getJSONArray("arenas");
					tempBattle.arena = arenas.getString(0);
					
					//raw battle start time
					tempBattle.at = item.getLong("time");

					WoTCWBot.scheduledBattlesOfOwnClanList.add(tempBattle);
					
					
				}
				WoTCWBot.LOGGER.trace("BattleSchedule parsed ("+WoTCWBot.scheduledBattlesOfOwnClanList.size()+" Battles)");
			}
			else
			{
				WoTCWBot.LOGGER.warn("BattleSchedule was not successfully delivered");
			}
			
			
		}
		catch(Exception e)
		{
			WoTCWBot.LOGGER.fatal("cannot parse battleschedule: "+e);
		}
		
	}
	
}
